package model

import (
	"context"
	"fmt"

	"github.com/Masterminds/squirrel"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"github.com/zeromicro/go-zero/core/stringx"
)

var _ QuestionModel = (*customQuestionModel)(nil)

var questionInsertColumns = stringx.Remove(questionFieldNames, "id")

type (
	// QuestionModel is an interface to be customized, add more methods here,
	// and implement the added methods in customQuestionModel.
	QuestionModel interface {
		questionModel
		withSession(session sqlx.Session) QuestionModel
		InsertBuilder() squirrel.InsertBuilder
		SelectBuilder() squirrel.SelectBuilder
		InsertGetId(ctx context.Context, session sqlx.Session, data *Question) (int64, error)
		Trans(ctx context.Context, fn func(context context.Context, session sqlx.Session) error) error
		FindOneByQstSort(ctx context.Context,session sqlx.Session,qstSort int64)(*Question,error)
		FindList(ctx context.Context,session sqlx.Session,serveyId int64)([]*Question,error)
	}

	customQuestionModel struct {
		*defaultQuestionModel
	}
)

// NewQuestionModel returns a model for the database table.
func NewQuestionModel(conn sqlx.SqlConn) QuestionModel {
	return &customQuestionModel{
		defaultQuestionModel: newQuestionModel(conn),
	}
}

func (m *customQuestionModel) withSession(session sqlx.Session) QuestionModel {
	return NewQuestionModel(sqlx.NewSqlConnFromSession(session))
}

func (m *customQuestionModel) InsertGetId(ctx context.Context, session sqlx.Session, data *Question) (int64, error) {
	query, args, err := m.InsertBuilder().Columns(questionInsertColumns...).
		Values(data.ServeyId,data.QstContent,data.Type,data.QstSort,data.IsMustAnswer,data.IsShow).
		Suffix("RETURNING \"id\"").
		ToSql()
	if err != nil {
		return 0, err
	}
	var id int64
	if session != nil {
		err = session.QueryRowPartialCtx(ctx, &id, query, args...)
	} else {
		err = m.conn.QueryRowPartialCtx(ctx, &id, query, args...)
	}
	if err != nil {
		return 0, err
	}

	return id, nil
}

func (m *customQuestionModel) InsertBuilder() squirrel.InsertBuilder {
	return squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar).Insert(m.table)
}

func (m *customQuestionModel) SelectBuilder() squirrel.SelectBuilder {
	return squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar).Select("question.*").From(m.table)
}

func (m *customQuestionModel)Trans(ctx context.Context, fn func(context context.Context, session sqlx.Session) error) error{
	return m.conn.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session)error{
		return fn(ctx, session)
	})
}

func (m *customQuestionModel)FindOneByQstSort(ctx context.Context,session sqlx.Session,qstSort int64)(*Question,error){
	query := fmt.Sprintf("select %s from %s where qst_sort = $1 limit 1", questionRows, m.table)
	var resp Question
	var err error
	if session != nil {
		err = session.QueryRowCtx(ctx,&resp,query,qstSort)
	}else{
		err = m.conn.QueryRowCtx(ctx, &resp, query, qstSort)
	}
	switch err {
	case nil:
		return &resp, nil
	case sqlx.ErrNotFound:
		return nil, ErrNotFound
	default:
		return nil, err
	}
}

func (m *customQuestionModel)FindList(ctx context.Context,session sqlx.Session,serveyId int64)([]*Question,error){
	builder := m.SelectBuilder().Where(squirrel.Eq{"servey_id": serveyId})
	query,values,err := builder.ToSql()
	if err != nil {
		return nil,err
	}
	var resp []*Question
	if session != nil {
		err = session.QueryRowsPartialCtx(ctx,&resp,query,values...)
	}else{
		err = m.conn.QueryRowsPartialCtx(ctx,&resp,query,values...)
	}
	return resp,err
}
